package com.baijiayun.sdk.util;

import com.baijiayun.sdk.annotation.NoDisposalEmpty;
import com.baijiayun.sdk.model.BaseRequest;
import com.google.common.base.CaseFormat;
import org.springframework.util.MultiValueMap;

import java.lang.reflect.Field;
import java.util.*;

public class RequestParamsUtils {

    public static void pushFieldToMap(Object obj, MultiValueMap<String, Object> map) throws IllegalAccessException {
        List<Field> baseFields = new ArrayList();
        Field[] fields = obj.getClass().getDeclaredFields();
        Class tempClass = BaseRequest.class;
        while (tempClass != null) {//当父类为null的时候说明到达了最上层的父类(Object类).
            baseFields.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            tempClass = tempClass.getSuperclass(); //得到父类,然后赋给自己
        }
        // 遍历父级字段
        for (Field field : baseFields) {
            putFieldToMap(field, map, obj);
        }
        // 遍历当前类的字段
        for (Field field : fields) {
            putFieldToMap(field, map, obj);
        }
    }

    public static void pushFieldToMap(Object obj, Map<String, Object> map) throws IllegalAccessException {
        List<Field> baseFields = new ArrayList();
        Field[] fields = obj.getClass().getDeclaredFields();
        Class tempClass = BaseRequest.class;
        while (tempClass != null) {//当父类为null的时候说明到达了最上层的父类(Object类).
            baseFields.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            tempClass = tempClass.getSuperclass(); //得到父类,然后赋给自己
        }
        // 遍历父级字段
        for (Field field : baseFields) {
            putFieldToMap(field, map, obj);
        }
        // 遍历当前类的字段
        for (Field field : fields) {
            putFieldToMap(field, map, obj);
        }
    }

    /**
     * 将Field类型的键值对, key为下划线形式, 放入map中
     *
     * @param field
     * @param map
     * @param targetObj
     * @throws IllegalAccessException
     */
    public static void putFieldToMap(Field field, Map<String, Object> map, Object targetObj) throws IllegalAccessException {
        field.setAccessible(true);
        //获取属性
        String key = field.getName();
        //获取属性值
        Object value = null;
        try {
            value = field.get(targetObj);
        } catch (Exception e) {
            return;
        }
        if (value == null) {
            return;
        }
        Class<?> type = field.getType();
        if (type == String.class) {
            if (value == null) {
                return;
            }
        }
        if (!field.isAnnotationPresent(NoDisposalEmpty.class)) {
            if (type == int.class) {
                if ((int) value == 0) {
                    return;
                }
            }
            if (type == long.class) {
                if ((long) value == 0) {
                    return;
                }
            }
        }
        map.put(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, key), value);
    }

    /**
     * 将Field类型的键值对, key为下划线形式, 放入map中
     *
     * @param field
     * @param map
     * @param targetObj
     * @throws IllegalAccessException
     */
    public static void putFieldToMap(Field field, MultiValueMap<String, Object> map, Object targetObj) throws IllegalAccessException {
        field.setAccessible(true);
        //获取属性
        String key = field.getName();
        //获取属性值
        Object value = field.get(targetObj);
        Class<?> type = field.getType();
        if (type == String.class) {
            if (value == null) {
                return;
            }
        }
        if (!field.isAnnotationPresent(NoDisposalEmpty.class)) {
            if (type == int.class) {
                if ((int) value == 0) {
                    return;
                }
            }
            if (type == long.class) {
                if ((long) value == 0) {
                    return;
                }
            }
        }
        map.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, key), value);
    }

    /**
     * 使用 Map按key进行排序
     *
     * @param map
     * @return
     */
    public static Map<String, List<Object>> sortMapByKey(MultiValueMap<String, Object> map, Comparator<String> comparator) {
        if (map == null || map.isEmpty()) {
            return null;
        }

        Map<String, List<Object>> sortMap = new TreeMap<>(
                comparator);
        sortMap.putAll(map);

        return sortMap;
    }
}
